package com.jt;

import redis.clients.jedis.Jedis;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 简易单点登录系统业务分析
 * 1)完成用户身份认证
 * 2)完成用户资源访问时的授权
 * SSO系统简易设计
 * 1)用户登录成功后，将用户信息存储到redis,并返回给客户端一个token
 * 2)用户携带token访问资源，资源服务器要检查token的有效性，并基于token查询用户信息确定
 * 用户是否已认证，假如已认证还要判定用户是否有这个资源的访问权限。
 */
public class SSODemo01 {
    /**
     * 基于用户名和密码执行登录操作，登录成功将用户状态和权限信息都存储到redis
     * @param username
     * @param password
     * @return 令牌对象(随机字符串，具备唯一特性)
     */
    static String doLogin(String username,String password){
        //1.判定参数的合法性
        if(username==null||"".equals(username))
            throw new IllegalArgumentException("用户名不能为空");
        if(password==null||"".equals(password))
            throw new IllegalArgumentException("密码不能为空");
        //2.判定用户是否存在(实际项目肯定是要查询数据库的)
        if(!"tony".equals(username))
            throw new RuntimeException("用户不存在");
        //3.判定密码是否正确
        if(!"123456".equals(password))
            throw new RuntimeException("密码不正确");
        //4.将用户信息存储到redis (key/value)
        Jedis jedis = JedisDataSource.getConnection();
        String token= UUID.randomUUID().toString();
        jedis.hset(token, "username", "tony");
        jedis.hset(token, "permission", "sys:resource:list,sys:resource:create");
        jedis.expire(token, 1);
        //5.返回token
        return token;
    }
    public static Object doGetResource(String token){
        //1.检验token是否为空
        if(token==null||"".equals(token))
            throw new IllegalArgumentException("请先登录认证");
        //2.基于token查询用户信息
        Jedis jedis = JedisDataSource.getConnection();
        Map<String, String> user = jedis.hgetAll(token);
        System.out.println("user="+user);
        //3.判定用户是否已登录，没有登录则抛出异常
        if(user==null||user.size()==0)
            throw new RuntimeException("登录超时，请重新登录");
        //4.判定用户是否有资源的访问权限,没有则抛出异常
        String permissionStr=user.get("permission");
        String[] permissions=permissionStr.split(",");
        List<String> permissionList = Arrays.asList(permissions);
        System.out.println(permissionList);
        if(!permissionList.contains("sys:resource:view"))
            throw new RuntimeException("你没有资源的访问权限");
        //5.返回你要访问的资源
        return "这就是用户的资源";
    }

    public static void main(String[] args) throws InterruptedException {
        //1.执行登录操作
        String username="tony";
        String password="123456";
        String token=doLogin(username,password);
        System.out.println("token="+token);
        //2.携带token访问用户的资源
        //Thread.sleep(2000);
        Object resource=doGetResource(token);
        System.out.println(resource);
    }
}